/* 
 * File:   PhotonEmitter.cpp
 * Author: neuma173
 * 
 * Created on November 29, 2011, 11:34 AM
 */

#include <pmap/PhotonEmitter.h>

PhotonEmitter::PhotonEmitter(const Vector3D& origin, double photonSize, Vector3D& photonColor, int photonDensity) {
    this->photonDensity = photonDensity;
    this->photonSize = photonSize;
    this->origin = origin;
    this->photonColor = photonColor;
}

PhotonEmitter::~PhotonEmitter() {
}

vector<Ray> PhotonEmitter::generatePhotonRays(){
    //build a unit cube around the light and sample each face
    Camera camera(origin, Vector3D(0,0.99,0)); //face nearly up to prevent colinear crossing
    camera.planeWidth = 1.0;
    camera.focalLength = 0.5;
    camera.lenseSize = 0;
    camera.buildBasis();

    vector<Ray> rays;
    
    int sectorCount = (int)(sqrt((double)photonDensity));

    double left, top, frameWidth, frameHeight;
    frameWidth = camera.planeWidth;
    frameHeight = frameWidth;;
    left = -frameWidth/2.0;
    top = -frameHeight/2.0;

    double pxlWidth = frameWidth;
    double pxlHeight = frameHeight;

    double directionX, directionY, directionZ;
    //left edge + x pixels + half a pixel
    directionX = left + pxlWidth*(1+0.5);
    //top edge + y pixels + half a pixel
    directionY = top + pxlHeight*(1+0.5);
    directionZ = -camera.focalLength;
    Vector3D pixelCenter((camera.u * directionX) +
                         (camera.v * directionY) +
                         (camera.w * directionZ) );

    //jitter them evenly over the pixel
    double subPixelWidth = pxlWidth/(double)sectorCount;
    double subPixelHeight = pxlHeight/(double)sectorCount;
    StochasticRNG srng;
    srng.generateRandomSet(photonDensity);

    for(int i=0; i<photonDensity; i++){
        double xOffset = (rand()/RAND_MAX)*subPixelWidth;
        double yOffset = (rand()/RAND_MAX)*subPixelHeight;
        int sp_row = i/sectorCount;
        int sp_col = i%sectorCount;
        double sp_x = left + pxlWidth + sp_col*subPixelWidth + xOffset;
        double sp_y = top + pxlHeight + sp_row*subPixelHeight + yOffset;

        //a random point on the lense

        double theta = 0;

        //lense size is diameter of lense
        //nth root pushes radius towards 1
        //this counter's the algorithm's tendancy
        //to favor the center of the circle

        double lenseX = 0;
        double lenseY = 0;

        Vector3D sampleOrigin = camera.origin + (camera.u * lenseX) + (camera.v * lenseY);

        //this is the 3D point the ray will pass through the image plane at
        Vector3D planePoint((camera.u * sp_x) +
                                   (camera.v * sp_y) +
                                   (camera.w * -camera.focalLength) + camera.origin);

        Vector3D sampleDirection = planePoint - sampleOrigin;

        Ray sample = Ray(sampleOrigin, sampleDirection.normalize(), 10);
        sample.batchNumber = -1;
        sample.sampleNumber = srng.getRandomSet()[i];
        rays.push_back(sample);
    }

    return rays;

    
}

void PhotonEmitter::castPhotons(vector<Ray>& paths, IntersectionStructure& is)
{

}